/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package kz.dasm.baing.rest;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import javax.inject.Inject;
import javax.sql.DataSource;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import kz.dasm.baing.Authenticator;
import kz.dasm.baing.db.DbApi;
import kz.dasm.baing.db.entity.BrandActionObjectInfo;
import kz.dasm.baing.db.entity.CompanyPerson;
import kz.dasm.baing.db.entity.ContactItem;
import kz.dasm.baing.db.entity.ContractFinance;
import kz.dasm.baing.db.entity.ContractObjectInfo;
import kz.dasm.baing.db.entity.CurrencyItem;
import kz.dasm.baing.db.entity.ObjectInfo;
import kz.dasm.baing.db.entity.ObjectItem;
import kz.dasm.baing.db.entity.ObjectTreeItem;
import kz.dasm.baing.rest.entity.DataResponse;
import kz.dasm.baing.rest.entity.ListDataResponse;
import kz.dasm.baing.rest.entity.TreeNode;

/**
 *
 * @author Kreedmart
 */
@Path("opr")
@Produces(MediaType.APPLICATION_JSON)
public class OperationService {

  private static final Logger logger = Logger.getLogger(
          OperationService.class.getName());
  
  @Inject
  Authenticator auth;
  @Inject
  DataSource ds;


  @GET
  @Path("/")
  @Produces(MediaType.TEXT_PLAIN)
  public String help() {
    Method[] methods = this.getClass().getMethods();
    StringBuilder sb = new StringBuilder();

    for (Method m : methods) {
      if (m.isAnnotationPresent(Path.class)) {
        Path path = m.getAnnotation(Path.class);

        if (m.isAnnotationPresent(GET.class)) {
          sb.append("GET");
        }

        if (m.isAnnotationPresent(POST.class)) {
          sb.append(" POST");
        }

        sb.append(" ").append(path.value()).append("\n");

        Annotation[][] paramAnts = m.getParameterAnnotations();
//        paramAnts.


      }
    }

    return sb.toString();
  }


  @POST
  @Path("getObjectsTree")
  public List<TreeNode> getObjectsTree() throws SQLException {

    DbApi dbApi = new DbApi(ds);
    List<ObjectTreeItem> items = dbApi.getObjectsTree(auth.getUserId());

    /*
     ListDataResponse<TreeNode> treeData = new ListDataResponse<TreeNode>();
     treeData.setData(getTreeNodes(null, items));
     treeData.setSuccess(true);
     */

    return getTreeNodes(null, items);
  }


  private List<TreeNode> getTreeNodes(
          Integer parentId, List<ObjectTreeItem> items) {
    List<TreeNode> nodes = new ArrayList<TreeNode>();

    for (ObjectTreeItem i : items) {
      if (i.getParentId() == parentId) {
        TreeNode node = new TreeNode();

        String id = (i.getParentId() == null ? "" : i.getParentId())
                + "/" + Integer.toString(i.getId());

        node.setId(id);

        node.setObjectId(i.getId());
        node.setText(i.getName());
        node.setLeaf(i.isLeaf());
        node.getChildren().addAll(getTreeNodes(i.getId(), items));
        node.setType(i.getTypeName());
        
        if (!node.getType().toLowerCase().equals("contract")) {
          node.setFactBudget(i.getFactBudget());
          node.setPlanBudget(i.getPlanBudget());
          node.setFactCharges(i.getFactCharges());
          node.setPlanCharges(i.getPlanCharges());
          node.setFactGrossGain(i.getFactGrossGain());
          node.setPlanGrossGain(i.getPlanGrossGain());
          node.setPlanProfitability(i.getPlanProfitability());
          node.setFactProfitability(i.getFactProfitability());
          node.setPlanPayments(i.getPlanPayments());
          node.setFactPayments(i.getFactPayments());          
        }
        nodes.add(node);
      }
    }
    return nodes;
  }


  @GET
//  @POST
  @Path("getObjectsByType")
  public ListDataResponse<ObjectItem> getObjectsByType(
          @QueryParam("typeName") String typeName) throws SQLException {

    DbApi dbApi = new DbApi(ds);
    List<ObjectItem> items = dbApi.getObjectsByType(typeName);
    
    ListDataResponse<ObjectItem> resp = new ListDataResponse<ObjectItem>();
    resp.setData(items);
    resp.setSuccess(true);

    return resp;
  }


//  @GET
  @POST
  @Path("getClientBrands")
  public ListDataResponse<ObjectItem> getClientBrands(
          @QueryParam("clientId") Integer clientId) throws SQLException {

    DbApi dbApi = new DbApi(ds);
    List<ObjectItem> items = dbApi.getClientBrands(clientId);
    
    ListDataResponse<ObjectItem> resp = new ListDataResponse<ObjectItem>();
    resp.setData(items);
    resp.setSuccess(true);

    return resp;
  }


//  @GET
  @POST
  @Path("getBrandActions")
  public ListDataResponse<ObjectItem> getBrandActions(
          @QueryParam("brandId") Integer brandId) throws SQLException {

    DbApi dbApi = new DbApi(ds);
    List<ObjectItem> items = dbApi.getBrandActions(brandId);
    
    ListDataResponse<ObjectItem> resp = new ListDataResponse<ObjectItem>();
    resp.setData(items);
    resp.setSuccess(true);

    return resp;
  }


//  @GET
  @POST
  @Path("getActionMedia")
  public ListDataResponse<ObjectItem> getActionMedia(
          @QueryParam("brandActionId") Integer brandActionId)
          throws SQLException {

    DbApi dbApi = new DbApi(ds);
    List<ObjectItem> items = dbApi.getActionMedia(brandActionId);
    
    ListDataResponse<ObjectItem> resp = new ListDataResponse<ObjectItem>();
    resp.setData(items);
    resp.setSuccess(true);

    return resp;
  }


//  @GET
  @POST
  @Path("getContractsByMedia")
  public ListDataResponse<ObjectItem> getContractsByMedia(
          @QueryParam("actionMediaId") Integer actionMediaId)
          throws SQLException {

    DbApi dbApi = new DbApi(ds);
    List<ObjectItem> items = dbApi.getContractsByMedia(
            auth.getUserId(), actionMediaId);
    
    ListDataResponse<ObjectItem> resp = new ListDataResponse<ObjectItem>();
    resp.setData(items);
    resp.setSuccess(true);

    return resp;
  }


//  @GET
  @POST
  @Path("getCompanyPersons")
  public ListDataResponse<CompanyPerson> getCompanyPersons(
          @QueryParam("companyId") Integer companyId)
          throws SQLException {

    DbApi dbApi = new DbApi(ds);
    List<CompanyPerson> items = dbApi.getCompanyPersons(companyId);
    
    ListDataResponse<CompanyPerson> resp = new ListDataResponse<CompanyPerson>();
    resp.setData(items);
    resp.setSuccess(true);

    return resp;
  }


  @GET
//  @POST
  @Path("getContacts")
  public ListDataResponse<ContactItem> getContacts(
          @QueryParam("subjectId") Integer subjectId)
          throws SQLException {

    DbApi dbApi = new DbApi(ds);
    List<ContactItem> items = dbApi.getContacts(subjectId);
    
    ListDataResponse<ContactItem> resp = new ListDataResponse<ContactItem>();
    resp.setData(items);
    resp.setSuccess(true);

    return resp;
  }


//  @GET
  @POST
  @Path("getObjectInfo")
  public DataResponse<ObjectInfo> getObjectInfo(
          @QueryParam("objectId") Integer objectId) throws SQLException {

    DbApi dbApi = new DbApi(ds);
    String objType = dbApi.getObjectType(objectId);
    ObjectInfo info;
    
    if ("Contract".equals(objType)) {
      info = dbApi.getObjectInfo(
              auth.getUserId(), objectId, ContractObjectInfo.class);

    } else if ("BrandAction".equals(objType)) {
      info = dbApi.getObjectInfo(
              auth.getUserId(), objectId, BrandActionObjectInfo.class);

    } else {
      info = dbApi.getObjectInfo(
              auth.getUserId(), objectId, ObjectInfo.class);
    }

    DataResponse<ObjectInfo> resp = new DataResponse<ObjectInfo>();
    resp.setData(info);
    resp.setSuccess(true);

    return resp;
  }


  @GET
  @Path("getCurrencies")
  public ListDataResponse<CurrencyItem> getCurrencies()
          throws SQLException {

    DbApi dbApi = new DbApi(ds);
    List<CurrencyItem> items = dbApi.getCurrencies();

    ListDataResponse<CurrencyItem> resp = new ListDataResponse<CurrencyItem>();
    resp.setData(items);
    resp.setSuccess(true);

    return resp;
  }


//  @GET
  @POST
  @Path("getContractFinance")
  public ListDataResponse<ContractFinance> getContractFinance(
          @FormParam("year") Integer year,
          @FormParam("contractId") Integer contractId) throws SQLException {        
    
    DbApi dbApi = new DbApi(ds);
    List<ContractFinance> items = dbApi.getContractFinance(
            auth.getUserId(), year, contractId);

    ListDataResponse<ContractFinance> resp = new ListDataResponse<ContractFinance>();
    resp.setData(items);
    resp.setSuccess(true);

    return resp;
  }
  
  @POST
  @Path("getContractFinanceByTree")
  public ListDataResponse<ContractFinance> getContractFinanceByTree(
          @FormParam("year") Integer year,
          @FormParam("objectId") Integer objectId) throws SQLException {
    
    DbApi dbApi = new DbApi(ds);
    List<ContractFinance> items = dbApi.getContractFinanceByTree(
            auth.getUserId(), year, objectId);

    ListDataResponse<ContractFinance> resp =
            new ListDataResponse<ContractFinance>();    
    resp.setData(items);
    resp.setSuccess(true);

    return resp;
  }  
}
